package com.zufangbao.earth.web.controller.particalsystem;

import java.math.BigDecimal;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.demo2do.core.entity.Result;
import com.zufangbao.earth.entity.particalsystem.VerifyCode;
import com.zufangbao.earth.handler.MessageHandler;
import com.zufangbao.earth.handler.SignatureHandler;
import com.zufangbao.earth.util.RegexUtils;
import com.zufangbao.gluon.api.electron.CashierInfo;
import com.zufangbao.gluon.handler.ResultHandler;
import com.zufangbao.gluon.opensdk.SignatureUtilsForPartner;
import com.zufangbao.gluon.spec.earth.BillElectronSpec;
import com.zufangbao.gluon.spec.global.GlobalCodeSpec;
import com.zufangbao.gluon.spec.quark.GlobalSpec4Quark;
import com.zufangbao.gluon.spec.quark.PaymentSpec;
import com.zufangbao.sun.entity.company.corp.App;
import com.zufangbao.sun.entity.contract.Contract;
import com.zufangbao.sun.entity.customer.Customer;
import com.zufangbao.sun.entity.house.House;
import com.zufangbao.sun.entity.order.Order;
import com.zufangbao.sun.handler.SmsHandler;
import com.zufangbao.sun.service.AppService;
import com.zufangbao.sun.service.CustomerService;
import com.zufangbao.sun.service.HouseService;
import com.zufangbao.sun.service.OrderService;

@Controller
@RequestMapping(value = BillElectronSpec.E_ELECTRON_NAME)
public class ElectronController {
	
	public static Log logger = LogFactory.getLog(ElectronController.class);
	
	@Autowired
	private AppService appService;
	
	@Autowired
	private SignatureHandler signatureHandler;
	
	@Autowired
	private MessageHandler messageHandler;
	
	@Autowired 
	@Qualifier("CLSmsHandler")
	private SmsHandler smsHandler;

	@Autowired
	private CustomerService customerService;
	
	@Autowired
	private HouseService houseService;
	
	@Autowired
	private OrderService orderService;
	
	@Autowired
	private ResultHandler resultHandler;
	
	@Value("#{remote['payment.remote']}")
	private String paymentRemote;
	
	@Value("#{remote['payment.returnUrl']}")
	private String returnUrl;
	
	@Value("#{remote['payment.notifyUrl']}")
	private String notifyUrl;
	
	@RequestMapping(value = BillElectronSpec.E_AUTH_NAME,method = RequestMethod.POST)
	public @ResponseBody String auth(
			@RequestParam(GlobalSpec4Quark.PARAM_APP_ID) String appId,
			@RequestParam(GlobalSpec4Quark.PARAM_CUSTOMER_ID) Long customerId,
			@RequestParam(GlobalSpec4Quark.PARAM_SIGNATURE) String signature) {
		
		try {
			logger.info("Begin to auth. Params:appId["+appId+"],cutomerId["+customerId+"],signature["+signature+"].");
			App app = appService.getApp(appId);
			
			if(null == app){
				logger.info("App does not exist.");
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_NO_AUTHORITY);
			}
			String appSecret = app.getAppSecret();
			
			boolean isValid = signatureHandler.checkAppSignature(appId, appSecret, signature, customerId.toString());
			logger.info("isValid"+isValid);
			if(!isValid){
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_NO_AUTHORITY);
			}
			
			Customer customer = customerService.getCustomer(appId, customerId);
			if(customer == null){
				logger.info("Customer not exist.");
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_NO_AUTHORITY);
			}
			
			String customerMobile = customer.getMobile();
			
			if (StringUtils.isEmpty(customerMobile)){
				logger.info("Mobile empty.");
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_ILLEGAL_PARAM);
			}
			logger.info("Auth success. mobile:"+customerMobile);
			return resultHandler.sucJsonResult(BillElectronSpec.E_CUSTOMER_MOBILE_NAME, customerMobile);
		} catch(Exception e) {
			logger.error("auth occur exception: " + e.getMessage());
			return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_SYSTEM);
		}
		
	}
	
	@RequestMapping(value = BillElectronSpec.E_V_CODE_NAME, method = RequestMethod.POST)
	public @ResponseBody String sendVerifyCode(@RequestParam(BillElectronSpec.E_CUSTOMER_MOBILE_NAME) String customerMobile) {
		
		try {
			logger.info("Begin to send v-code. Params:customerMobile["+customerMobile+"].");
			if (!RegexUtils.isMobile(customerMobile)) {
				return resultHandler.errorJsonResult(GlobalCodeSpec.VerifyCodeSpec.REQUEST_ILLEGAL);
			}
			
			VerifyCode verifyCode = messageHandler.generateVerifyCode();
			
			Result smsResult = smsHandler.sendSms(customerMobile, verifyCode.getContent());
			
			if(!smsResult.isValid()){
				logger.info("Send v-code fail!");
				return resultHandler.errorJsonResult(GlobalCodeSpec.VerifyCodeSpec.SEND_FAIL);
			}
			logger.info("Send v-code success. V-code: "+ verifyCode.getCode());
			return resultHandler.sucJsonResult(BillElectronSpec.E_VERIFY_CODE_KEY, verifyCode.getCode());
			
		} catch (Exception e){
			logger.error("Send v-code occurs exception: " + e.getMessage());
			return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_SYSTEM);
		}
	}

	@RequestMapping(value = BillElectronSpec.E_RETURN_CASHIERINFO_NAME, method = RequestMethod.POST)
	public @ResponseBody String viewOrderInfo(@RequestParam(PaymentSpec.PaymentParam.UNIQUE_BILL_ID) String uniqueBillId) {
		try {
			logger.info("Begin to create cashierInfo. Params: uniqueBillId["+uniqueBillId+"].");
			Order currentOrder = orderService.getOrderByUniqueBillId(uniqueBillId);
			if(currentOrder == null){
				logger.info("currentOrder is null");
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_ILLEGAL_PARAM);
			}
			
			Customer customer = currentOrder.getCustomer();
			
			Contract contract = currentOrder.getContract();
			
			if (null == contract){
				logger.info("contract is null");
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_ILLEGAL_PARAM);
			}
			
			House house = contract.getHouse();
			
			if(null == house || null == customer){
				logger.info("house or customer is null");
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_ILLEGAL_PARAM);
			}
			CashierInfo cashierInfo = new CashierInfo(customer.getName(), customer.getMobile(), house.getAddress(), currentOrder.getStartDate(), currentOrder.getEndDate());
			logger.info("Get cashierInfo susccess. cashierInfo: "+cashierInfo);
			return resultHandler.sucJsonResult(BillElectronSpec.E_CASHIER_INFO_NAME, cashierInfo);
		} catch (Exception e){
			logger.error("Get cashierInfo occurs error. Message:"+e.getMessage());
			return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_SYSTEM);
		}
	}
	
	@RequestMapping(value = BillElectronSpec.E_PAYMENT_URL_NAME, method = RequestMethod.POST)
	public @ResponseBody String paymentUrl(@RequestParam(PaymentSpec.PaymentParam.UNIQUE_BILL_ID) String uniqueBillId,
											@RequestParam(PaymentSpec.PaymentParam.PARAM_PAID_RENT) String payAmount){
		
		try {
			logger.info("Begin to create pamentUrl. Params: uniqueBillId["+uniqueBillId+"],payAmount["+payAmount+"].");
			if(!RegexUtils.isRealNumber(payAmount)) {
				logger.info("PayAmount is not a real number.");
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_ILLEGAL_PARAM);
			}
			
			BigDecimal currentPayAmount = new BigDecimal(payAmount);
			String appId = orderService.extractAppIdFromUniqueBillId(uniqueBillId);
			logger.info("Extract appId from uniqueBillId, appId is [" + appId +"].");
			if (appId == null){
				
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_ILLEGAL_PARAM);
			}
			
			Order currentOrder = orderService.getOrderByUniqueBillId(uniqueBillId);
			if(currentOrder == null){
				logger.info("currentOrder is null.");
				return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_ILLEGAL_PARAM);
			}
			App app = appService.getApp(appId);
			
			String payNo = currentOrder.createELectronPayNo();
			
			String paymentUrl = SignatureUtilsForPartner.createCheckoutCounterUrl(paymentRemote, app.getAppId(), app.getAppSecret(), currentOrder.getOrderNo(), currentPayAmount.toString(), payNo, returnUrl, notifyUrl);
			logger.info("Create paymentUrl success. paymentUrl :["+paymentUrl+"].");
			return resultHandler.sucJsonResult(BillElectronSpec.E_PAYMENT_URL_NAME, paymentUrl);
		} catch (Exception e) {
			logger.error("create pamentUrl occurs error. Message:"+e.getMessage());
			return resultHandler.errorJsonResult(GlobalCodeSpec.GeneralErrorCode.ERROR_SYSTEM);
		}
	}
	

}
